use crate::src::src::compare_int::{int_compare, int_equal};
use crate::src::src::list::{
    list_append, list_data, list_find_data, list_free, list_iter_has_more, list_iter_next,
    list_iter_remove, list_iterate, list_length, list_next, list_nth_data, list_nth_entry,
    list_prepend, list_prev, list_remove_data, list_remove_entry, list_sort, list_to_array,
};
use crate::src::struct_and_type::{ListEntry, ListIterator, ListValue, UnitTestFunction};
use crate::src::test::alloc_testing::{alloc_test_free, alloc_test_set_limit};
use crate::src::test::framework::run_tests;

#[no_mangle]
pub static mut variable1_test_list: i32 = 50;
#[no_mangle]
pub static mut variable2_test_list: i32 = 0;
#[no_mangle]
pub static mut variable3_test_list: i32 = 0;
#[no_mangle]
pub static mut variable4_test_list: i32 = 0;
#[no_mangle]
pub extern "C" fn generate_list_test_list() -> *mut ListEntry {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    return list;
}
#[no_mangle]
pub extern "C" fn check_list_integrity(mut list: *mut ListEntry) {
    let mut prev: *mut ListEntry = 0 as *mut ListEntry;
    let mut rover: *mut ListEntry = 0 as *mut ListEntry;
    prev = 0 as *mut ListEntry;
    rover = list;
    while !rover.is_null() {
        assert!(list_prev(rover) == prev);
        prev = rover;
        rover = list_next(rover);
    }
}
#[no_mangle]
pub extern "C" fn test_list_append() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(list_length(list) == 4 as u32);
    assert!(
        list_nth_data(list, 0 as u32)
            == (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 1 as u32)
            == (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 2 as u32)
            == (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 3 as u32)
            == (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    );
    alloc_test_set_limit(0 as i32);
    assert!(list_length(list) == 4 as u32);
    assert!((list_append(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(list_length(list) == 4 as u32);
    check_list_integrity(list);
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_prepend() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    assert!(!(list_prepend(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_prepend(
        &mut list,
        (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_prepend(
        &mut list,
        (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(!(list_prepend(
        &mut list,
        (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    check_list_integrity(list);
    assert!(
        list_nth_data(list, 0 as u32)
            == (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 1 as u32)
            == (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 2 as u32)
            == (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 3 as u32)
            == (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    );
    alloc_test_set_limit(0 as i32);
    assert!(list_length(list) == 4 as u32);
    assert!((list_prepend(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(list_length(list) == 4 as u32);
    check_list_integrity(list);
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_free() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    list_free(list);
    list_free(core::ptr::null_mut());
}
#[no_mangle]
pub extern "C" fn test_list_next() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut rover: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    rover = list;
    assert!(list_data(rover) == (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue);
    rover = list_next(rover);
    assert!(list_data(rover) == (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue);
    rover = list_next(rover);
    assert!(list_data(rover) == (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue);
    rover = list_next(rover);
    assert!(list_data(rover) == (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue);
    rover = list_next(rover);
    assert!(rover.is_null());
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_nth_entry() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut entry: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    entry = list_nth_entry(list, 0 as u32);
    assert!(list_data(entry) == (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue);
    entry = list_nth_entry(list, 1 as u32);
    assert!(list_data(entry) == (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue);
    entry = list_nth_entry(list, 2 as u32);
    assert!(list_data(entry) == (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue);
    entry = list_nth_entry(list, 3 as u32);
    assert!(list_data(entry) == (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue);
    entry = list_nth_entry(list, 4 as u32);
    assert!(entry.is_null());
    entry = list_nth_entry(list, 400 as u32);
    assert!(entry.is_null());
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_nth_data() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    assert!(
        list_nth_data(list, 0 as u32)
            == (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 1 as u32)
            == (unsafe { &mut variable2_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 2 as u32)
            == (unsafe { &mut variable3_test_list }) as *mut i32 as ListValue
    );
    assert!(
        list_nth_data(list, 3 as u32)
            == (unsafe { &mut variable4_test_list }) as *mut i32 as ListValue
    );
    assert!((list_nth_data(list, 4 as u32)).is_null());
    assert!((list_nth_data(list, 400 as u32)).is_null());
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_length() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    assert!(list_length(list) == 4 as u32);
    assert!(!(list_prepend(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(list_length(list) == 5 as u32);
    list_free(list);
    assert!(list_length(core::ptr::null_mut()) == 0 as u32);
}
#[no_mangle]
pub extern "C" fn test_list_remove_entry() {
    let mut empty_list: *mut ListEntry = 0 as *mut ListEntry;
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut entry: *mut ListEntry = 0 as *mut ListEntry;
    list = generate_list_test_list();
    entry = list_nth_entry(list, 2 as u32);
    assert!(list_remove_entry(&mut list, entry) != 0);
    assert!(list_length(list) == 3 as u32);
    check_list_integrity(list);
    entry = list_nth_entry(list, 0 as u32);
    assert!(list_remove_entry(&mut list, entry) != 0);
    assert!(list_length(list) == 2 as u32);
    check_list_integrity(list);
    assert!(list_remove_entry(&mut list, 0 as *mut ListEntry) == 0);
    assert!(list_remove_entry(&mut empty_list, 0 as *mut ListEntry) == 0);
    list_free(list);
    list = 0 as *mut ListEntry;
    assert!(!(list_append(
        &mut list,
        (unsafe { &mut variable1_test_list }) as *mut i32 as ListValue
    ))
    .is_null());
    assert!(!list.is_null());
    assert!(list_remove_entry(&mut list, list) != 0);
    assert!(list.is_null());
    list = generate_list_test_list();
    entry = list_nth_entry(list, 3 as u32);
    assert!(list_remove_entry(&mut list, entry) != 0);
    check_list_integrity(list);
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_remove_data() {
    let mut entries: [i32; 13] = [ 89, 4, 23, 42, 4, 16, 15, 4, 8, 99, 50, 30, 4,
    ];
    let mut num_entries: u32 = (::core::mem::size_of::<[i32; 13]>() as u64)
        .wrapping_div(::core::mem::size_of::<i32>() as u64) as u32;
    let mut val: i32 = 0;
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut i: u32 = 0;
    list = 0 as *mut ListEntry;
    i = 0 as u32;
    while i < num_entries {
        assert!(!(list_prepend(
            &mut list,
            (unsafe { &mut *entries.as_mut_ptr().offset(i as isize) }) as *mut i32 as ListValue,
        ))
        .is_null());
        i = i.wrapping_add(1);
        i;
    }
    val = 0;
    assert!(
        list_remove_data(
            &mut list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
            &mut val as *mut i32 as ListValue,
        ) == 0 as u32
    );
    val = 56;
    assert!(
        list_remove_data(
            &mut list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
            &mut val as *mut i32 as ListValue,
        ) == 0 as u32
    );
    check_list_integrity(list);
    val = 8;
    assert!(
        list_remove_data(
            &mut list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
            &mut val as *mut i32 as ListValue,
        ) == 1 as u32
    );
    assert!(list_length(list) == num_entries.wrapping_sub(1 as i32 as u32));
    check_list_integrity(list);
    val = 4;
    assert!(
        list_remove_data(
            &mut list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
            &mut val as *mut i32 as ListValue,
        ) == 4 as u32
    );
    assert!(list_length(list) == num_entries.wrapping_sub(5 as i32 as u32));
    check_list_integrity(list);
    val = 89;
    assert!(
        list_remove_data(
            &mut list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
            &mut val as *mut i32 as ListValue,
        ) == 1 as u32
    );
    assert!(list_length(list) == num_entries.wrapping_sub(6 as i32 as u32));
    check_list_integrity(list);
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_sort() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut entries: [i32; 13] = [ 89, 4, 23, 42, 4, 16, 15, 4, 8, 99, 50, 30, 4,
    ];
    let mut sorted: [i32; 13] = [ 4, 4, 4, 4, 8, 15, 16, 23, 30, 42, 50, 89, 99,
    ];
    let mut num_entries: u32 = (::core::mem::size_of::<[i32; 13]>() as u64)
        .wrapping_div(::core::mem::size_of::<i32>() as u64) as u32;
    let mut i: u32 = 0;
    list = 0 as *mut ListEntry;
    i = 0 as u32;
    while i < num_entries {
        assert!(!(list_prepend(
            &mut list,
            (unsafe { &mut *entries.as_mut_ptr().offset(i as isize) }) as *mut i32 as ListValue,
        ))
        .is_null());
        i = i.wrapping_add(1);
        i;
    }
    list_sort(
        &mut list,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    assert!(list_length(list) == num_entries);
    i = 0 as u32;
    while i < num_entries {
        let mut value: *mut i32 = 0 as *mut i32;
        value = list_nth_data(list, i) as *mut i32;
        assert!((unsafe { *value }) == sorted[i as usize]);
        i = i.wrapping_add(1);
        i;
    }
    list_free(list);
    list = 0 as *mut ListEntry;
    list_sort(
        &mut list,
        Some(int_compare as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
    );
    assert!(list.is_null());
}
#[no_mangle]
pub extern "C" fn test_list_find_data() {
    let mut entries: [i32; 10] = [ 89, 23, 42, 16, 15, 4, 8, 99, 50, 30,
    ];
    let mut num_entries: i32 = (::core::mem::size_of::<[i32; 10]>() as u64)
        .wrapping_div(::core::mem::size_of::<i32>() as u64) as i32;
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut result: *mut ListEntry = 0 as *mut ListEntry;
    let mut i: i32 = 0;
    let mut val: i32 = 0;
    let mut data: *mut i32 = 0 as *mut i32;
    list = 0 as *mut ListEntry;
    i = 0;
    while i < num_entries {
        assert!(!(list_append(
            &mut list,
            (unsafe { &mut *entries.as_mut_ptr().offset(i as isize) }) as *mut i32 as ListValue,
        ))
        .is_null());
        i += 1;
        i;
    }
    i = 0;
    while i < num_entries {
        val = entries[i as usize];
        result = list_find_data(
            list,
            Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32),
            &mut val as *mut i32 as ListValue,
        );
        assert!(!result.is_null());
        data = list_data(result) as *mut i32;
        assert!((unsafe { *data }) == val);
        i += 1;
        i;
    }
    val = 0;
    assert!((list_find_data(
        list,
        Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
        &mut val as *mut i32 as ListValue,
    ))
    .is_null());
    val = 56;
    assert!((list_find_data(
        list,
        Some(int_equal as unsafe extern "C" fn(*mut (), *mut ()) -> i32,),
        &mut val as *mut i32 as ListValue,
    ))
    .is_null());
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_to_array() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut array: *mut *mut () = 0 as *mut *mut ();
    list = generate_list_test_list();
    array = list_to_array(list);
    assert!(
        (unsafe { *array.offset(0 as i32 as isize) })
            == (unsafe { &mut variable1_test_list }) as *mut i32 as *mut ()
    );
    assert!(
        (unsafe { *array.offset(1 as i32 as isize) })
            == (unsafe { &mut variable2_test_list }) as *mut i32 as *mut ()
    );
    assert!(
        (unsafe { *array.offset(2 as i32 as isize) })
            == (unsafe { &mut variable3_test_list }) as *mut i32 as *mut ()
    );
    assert!(
        (unsafe { *array.offset(3 as i32 as isize) })
            == (unsafe { &mut variable4_test_list }) as *mut i32 as *mut ()
    );
    alloc_test_free(array as *mut ());
    alloc_test_set_limit(0 as i32);
    array = list_to_array(list);
    assert!(array.is_null());
    list_free(list);
}
#[no_mangle]
pub extern "C" fn test_list_iterate() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut iter: ListIterator = ListIterator {
        prev_next: 0 as *mut *mut ListEntry,
        current: 0 as *mut ListEntry,
    };
    let mut i: i32 = 0;
    let mut a: i32 = 0;
    let mut counter: i32 = 0;
    let mut data: *mut i32 = 0 as *mut i32;
    list = 0 as *mut ListEntry;
    i = 0;
    while i < 50 {
        assert!(!(list_prepend(&mut list, &mut a as *mut i32 as ListValue)).is_null());
        i += 1;
        i;
    }
    counter = 0;
    list_iterate(&mut list, &mut iter);
    list_iter_remove(&mut iter);
    while list_iter_has_more(&mut iter) != 0 {
        data = list_iter_next(&mut iter) as *mut i32;
        counter += 1;
        counter;
        if counter % 2 == 0 {
            list_iter_remove(&mut iter);
            list_iter_remove(&mut iter);
        }
    }
    assert!((list_iter_next(&mut iter)).is_null());
    list_iter_remove(&mut iter);
    assert!(counter == 50);
    assert!(list_length(list) == 25 as u32);
    list_free(list);
    list = 0 as *mut ListEntry;
    counter = 0;
    list_iterate(&mut list, &mut iter);
    while list_iter_has_more(&mut iter) != 0 {
        data = list_iter_next(&mut iter) as *mut i32;
        counter += 1;
        counter;
    }
    assert!(counter == 0);
}
#[no_mangle]
pub extern "C" fn test_list_iterate_bad_remove() {
    let mut list: *mut ListEntry = 0 as *mut ListEntry;
    let mut iter: ListIterator = ListIterator {
        prev_next: 0 as *mut *mut ListEntry,
        current: 0 as *mut ListEntry,
    };
    let mut values: [i32; 49] = [0; 49];
    let mut i: i32 = 0;
    let mut val: *mut i32 = 0 as *mut i32;
    list = 0 as *mut ListEntry;
    i = 0;
    while i < 49 {
        values[i as usize] = i;
        assert!(!(list_prepend(
            &mut list,
            (unsafe { &mut *values.as_mut_ptr().offset(i as isize) }) as *mut i32 as ListValue,
        ))
        .is_null());
        i += 1;
        i;
    }
    list_iterate(&mut list, &mut iter);
    while list_iter_has_more(&mut iter) != 0 {
        val = list_iter_next(&mut iter) as *mut i32;
        if (unsafe { *val }) % 2 == 0 {
            assert!(
                list_remove_data(
                    &mut list,
                    Some(
                        int_equal
                            as unsafe extern "C" fn(*mut (), *mut ()) -> i32,
                    ),
                    val as ListValue,
                ) != 0 as u32
            );
            list_iter_remove(&mut iter);
        }
    }
    list_free(list);
}
static mut tests_test_list: [UnitTestFunction; 15] = {
    [
        Some(test_list_append as unsafe extern "C" fn() -> ()),
        Some(test_list_prepend as unsafe extern "C" fn() -> ()),
        Some(test_list_free as unsafe extern "C" fn() -> ()),
        Some(test_list_next as unsafe extern "C" fn() -> ()),
        Some(test_list_nth_entry as unsafe extern "C" fn() -> ()),
        Some(test_list_nth_data as unsafe extern "C" fn() -> ()),
        Some(test_list_length as unsafe extern "C" fn() -> ()),
        Some(test_list_remove_entry as unsafe extern "C" fn() -> ()),
        Some(test_list_remove_data as unsafe extern "C" fn() -> ()),
        Some(test_list_sort as unsafe extern "C" fn() -> ()),
        Some(test_list_find_data as unsafe extern "C" fn() -> ()),
        Some(test_list_to_array as unsafe extern "C" fn() -> ()),
        Some(test_list_iterate as unsafe extern "C" fn() -> ()),
        Some(test_list_iterate_bad_remove as unsafe extern "C" fn() -> ()),
        None,
    ]
};
fn main_0_test_list(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    run_tests(unsafe { tests_test_list.as_mut_ptr() });
    return 0;
}
pub fn main_test_list() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(main_0_test_list(
            (args.len() - 1) as i32,
            args.as_mut_ptr() as *mut *mut i8,
        ) as i32)
    }
}
